﻿using Jint;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.IO;
using T.FAS.Runtime.Base.Entity;
using System.Reflection;
using System.Text;
using System.Text.RegularExpressions;
using T.FAS.Runtime.Expression.Entity;
using T.FAS.Runtime.Expression.Service;
using System.Dynamic;
using T.FAS.Runtime.Expression.Plugin;
using T.FAS.Runtime.Action.SPI;
using T.FAS.Runtime.Action.Service;
using System.Threading.Tasks;
using System.Threading;
using System.Diagnostics;
using System.Transactions;
using T.ServiceComponent.DataAccessEx.Core;

namespace T.FAS.Runtime.Expression.UnitTest
{
    [TestClass]
    public class ActionUnit
    {

        /// <summary>
        /// 表达式执行
        /// </summary>
        [TestMethod]
        public void ExecuteActionExpr()
        {
            Dictionary<string, object> dic = new Dictionary<string, object>();
            dic.Add("test", new ExpressionUnit());
            var expr = @"
            //var userID = LocalVars.InParam_UserID;
//var startTime = Funcs.DateTimeToDate(LocalVars.InParam_StartTime);
//var finishTime = Funcs.DateTimeToDate(LocalVars.InParam_FinishTime);
startTime = Funcs.DateTimeToDate(startTime);
finishTime = Funcs.DateTimeToDate(finishTime);

var tasks = DataQuery.GetPersonalAllUserTask(userID, startTime, finishTime, 0, 0, null, null);
if (tasks == undefined || tasks == null || tasks.List == null || tasks.List.length <= 0) {
    throw '未能获取到指定用户的工作日志信息' + tasks;
    //return null;
}

        var minStartDate = null;
        var maxFinishDate = null;
for (let index = 0; index<tasks.List.length; index++) {
    var task = tasks.List[index];
    if (minStartDate == null)
        minStartDate = Funcs.DateTimeToDate(task.MyPlanStartTime);
    else if (minStartDate > task.MyPlanStartTime)
        minStartDate = Funcs.DateTimeToDate(task.MyPlanStartTime);

    if (maxFinishDate == null)
        maxFinishDate = Funcs.DateTimeToDate(task.MyPlanFinishTime);
    else if (maxFinishDate<task.MyPlanFinishTime)
        maxFinishDate = Funcs.DateTimeToDate(task.MyPlanFinishTime);
}

if (minStartDate<startTime)
    minStartDate = startTime;
if (maxFinishDate > finishTime)
    maxFinishDate = finishTime;

var days = Funcs.DiffDays(minStartDate, maxFinishDate);

    //计算工作日信息
    var result = [];
for (let i = 0; i <= days; i++) {
    var tempDate = Funcs.FormatDateTime(Funcs.AddDays(minStartDate, i), 'yyyy-MM-dd');
    result.push({ Date: tempDate, PlanHours: 0, BurnHours: 0, Capability: 0 });
}

//先获取用户容量信息，因为包含了Team和Org
//先获取用户的迭代容量，包含对应的Team以及Org
//IterationID\PlanHours\DO_DEP_Iteration_Team\DO_DEP_Iteration_PlanStartDate\DO_DEP_Iteration_PlanFinishDate\DO_DEP_Teams_DepartmentID
var userCapacity = DataQuery.GetUserIterationCapacity(userID, minStartDate, maxFinishDate, 0, 0, null, null);
if (userCapacity == undefined || userCapacity == null || userCapacity.List.length <= 0)
{
    throw '当前用户未设置容量信息！';
}

for (let j = 0; j < userCapacity.List.length; j++)
{
    var userInfoOrg = userCapacity.List[j].DO_DEP_Teams_DepartmentID;
    var userInfoTeam = userCapacity.List[j].DO_DEP_Iteration_Team;

    //查询对应Team和Org的日历,从Result中移除所有休息日
    var noworkDays = DataQuery.GetUserWorkCalendar(userInfoOrg, userInfoTeam, minStartDate, maxFinishDate, 0, 0, null, null);
    if (noworkDays != undefined && noworkDays != null && noworkDays.List.length > 0)
    {
        for (let i = 0; i < noworkDays.List.length; i++)
        {
            result = result.filter(x => x.Date != Funcs.FormatDateTime(noworkDays.List[i], 'yyyy-MM-dd'));
            //delete result[noworkDays.List[i]];
        }
    }
}


//计算剩余工作量
var taskCalcInfo = [];
for (let index = 0; index < tasks.List.length; index++)
{
    var task = tasks.List[index];
    var myPlanStartTime = Funcs.DateTimeToDate(task.MyPlanStartTime);
    var myPlanFinishTime = Funcs.DateTimeToDate(task.MyPlanFinishTime);
    var continueDays = Funcs.DiffDays(myPlanStartTime, myPlanFinishTime);
    var burnDays = 0;
    if (Funcs.CurrDate() >= myPlanStartTime)
    {
        if (Funcs.CurrDate() > myPlanFinishTime)
            burnDays = Funcs.DiffDays(myPlanStartTime, myPlanFinishTime);
        else
            burnDays = Funcs.DiffDays(myPlanStartTime, Funcs.CurrDate());
    }
    var remainDays = 0;
    if (Funcs.CurrDate() >= myPlanStartTime)
    {
        if (Funcs.CurrDate() > myPlanFinishTime)
            remainDays = 0;
        else
            remainDays = Funcs.DiffDays(Funcs.CurrDate(), myPlanFinishTime);
    }
    else
        remainDays = Funcs.DiffDays(myPlanStartTime, myPlanFinishTime);

    var historyDays = 0;
    if (Funcs.CurrDate() >= myPlanStartTime)
    {
        if (Funcs.CurrDate() > myPlanFinishTime)
            historyDays = Funcs.DiffDays(myPlanStartTime, myPlanFinishTime);
        else
            historyDays = Funcs.DiffDays(myPlanStartTime, Funcs.CurrDate());
    }


    if (noworkDays != undefined && noworkDays != null && noworkDays.List.length > 0)
    {
        for (let i = 0; i < noworkDays.List.length; i++)
        {
            if (continueDays > 0 && noworkDays.List[i] >= myPlanStartTime && noworkDays.List[i] <= myPlanFinishTime)
            {
                continueDays = continueDays - 1;
            }
            if (burnDays > 0 && noworkDays.List[i] >= myPlanStartTime && noworkDays.List[i] <= Funcs.CurrDate())
            {
                burnDays = burnDays - 1;
            }
            if (remainDays > 0 && noworkDays.List[i] >= Funcs.CurrDate() && noworkDays.List[i] <= myPlanFinishTime)
            {
                remainDays = remainDays - 1;
            }
            if (historyDays > 0 && noworkDays.List[i] < Funcs.CurrDate() && noworkDays.List[i] >= myPlanStartTime)
            {
                historyDays = historyDays - 1;
            }
        }
    }

    var remainHoursByDay = 0;
    if (remainDays <= 0)
        remainHoursByDay = task.RemainingHours;
    else
        remainHoursByDay = (task.RemainingHours / remainDays);

    var burnHoursByDay = 0;
    if (burnDays <= 0)
        burnHoursByDay = task.SpentHours;
    else
        burnHoursByDay = (task.SpentHours / burnDays);

    var historyPlanHoursByDay = 0;
    if (historyDays <= 0)
        historyPlanHoursByDay = (task.PlanHours / continueDays);
    else
        historyPlanHoursByDay = ((task.PlanHours - task.RemainingHours) / historyDays);

    taskCalcInfo.push({ Days: continueDays, BurnDays: burnDays, RemainDays: remainDays, HistoryDays: historyDays, HistoryPlanHoursByDay: historyPlanHoursByDay, RemainHoursByDay: remainHoursByDay, BurnHoursByDay: burnHoursByDay, StartDate: myPlanStartTime, FinishDate: myPlanFinishTime });
}

for (let index = 0; index < taskCalcInfo.length; index++)
{
    var task = taskCalcInfo[index];
    var taskCalcInfoDays = Funcs.DiffDays(task.StartDate, task.FinishDate);

    for (let ii = 0; ii < taskCalcInfoDays; ii++)
    {
        var ttDate = Funcs.AddDays(task.StartDate, ii);
        var tmp = result.find(x => x.Date == Funcs.FormatDateTime(ttDate, 'yyyy-MM-dd'));
        if (tmp)
        {
            if (ttDate < Funcs.CurrDate())
                tmp.PlanHours += task.HistoryPlanHoursByDay;
            else
                tmp.PlanHours += task.RemainHoursByDay;

            if (ttDate < Funcs.CurrDate())
                tmp.BurnHours += task.BurnHoursByDay;
        }
    }
}

//计算容量

if (userCapacity != undefined && userCapacity != null && userCapacity.List.length > 0)
{
    for (let index = 0; index < userCapacity.List.length; index++)
    {
        var userCapacityItem = userCapacity.List[index];
        var iternationDays = Funcs.DiffDays(userCapacityItem.DO_DEP_Iteration_PlanStartDate, userCapacityItem.DO_DEP_Iteration_PlanFinishDate);
        for (let y = 0; y < iternationDays; y++)
        {
            var tempDate = Funcs.AddDays(Funcs.DateTimeToDate(userCapacityItem.DO_DEP_Iteration_PlanStartDate), y);
            var tmp = result.find(x => x.Date == Funcs.FormatDateTime(tempDate, 'yyyy-MM-dd'));
            if (tmp)
            {
                tmp.Capability += userCapacityItem.PlanHours;
            }
        }
    }
}
if (!result)
{
    throw '调试' + 'result数据为空' + JSON.stringify(result) + '用户ID' + userID + '起始时间' + startTime + '终止时间' + finishTime;
}
//throw '调试'+JSON.stringify(result);
return result;

/*
LocalVars.varUserWorkHours= tResult;

var totalPlanHours =0;
var totalCapacity=0;
for(let i=0;i<tResult.length;i++)
{
    totalCapacity += tResult[i].Capability;
    totalPlanHours +=tResult[i].PlanWorkingHours
}
*/
";
            ExprResult exprResult = ExprService.GetInstance.JSExecute(expr, dic);
            Assert.IsTrue(exprResult.State == ResultState.Fail);
        }/// <summary>
         /// 表达式执行
         /// </summary>
        [TestMethod]
        public void ExecuteActionExpr2()
        {
            Dictionary<string, object> dic = new Dictionary<string, object>();
            dic.Add("test", new ExpressionUnit());
            var expr = @"
throw 'eee';
startDate = Funcs.DateTimeToDate(startDate);
finishDate = Funcs.DateTimeToDate(finishDate);

var tResult= Action.GetPersonalPlanHoursByDay(userID,startDate,finishDate);
//var tResult= Action.GetPersonalPlanHoursByDay('e3e366dc-f14b-4eb2-8c72-5ac35f0f6660','2022-01-10 00:00:00','2022-02-08 08:00:00');


var result ={Saturation:0,Capacity:0,RemainHours:0};


if(tResult == undefined || tResult == null||tResult.List ==null || tResult.List.length<=0)
    return result;


var totalPlanHours =0;
var totalCapacity=0;
for(let i=0;i<tResult.List.length;i++)
{
    totalCapacity += Funcs.StringToDecimal( tResult.List[i].Capability);
    totalPlanHours +=Funcs.StringToDecimal( tResult.List[i].PlanHours);
}

if(totalCapacity !=null)
{
    result.Saturation = (totalPlanHours/totalCapacity).toFixed(2);
}
result.Capacity = totalCapacity.toFixed(1);
result.RemainHours = totalPlanHours.toFixed(1);

return result;
";
            ExprResult exprResult = ExprService.GetInstance.JSExecute(expr, dic);
            Assert.IsTrue(exprResult.State == ResultState.Fail);
        }
        /// <summary>
        /// Action
        /// </summary>
        [TestMethod]
        public void ExecuteAction()
        {
            Dictionary<string, object> dic = new Dictionary<string, object>();
            var expr = @"var filter = { };
            filter.MetaDataType = 'CompositeDataObject';
            filter.MetaDataCode = 'CDO_DO_TemplateV2';
            filter.BillID = '1';
            Action.Action_GetChangeLog(filter)";
            ExprResult exprResult = ExprService.GetInstance.JSExecute(expr, dic);
            Assert.IsTrue(exprResult.State == ResultState.Fail);
        }
        /// <summary>
        /// CDOAction
        /// </summary>
        [TestMethod]
        public void ExecuteCDOAction()
        {
            Dictionary<string, object> dic = new Dictionary<string, object>();
            string ID = Guid.NewGuid().ToString();
            var expr = "var record = {};";
            expr += $@"
            record.ActionID = null;
            record.ActionCode = null;
            record.ActionName = null;
            record.ID = '{ID}';
            record.Code = '1';
            record.Name = '2';
            record.Creator = '';
            record.CreateTime = '';
            record.LastModifier = '';
            record.LastModifierName = '';
            record.LastModifyTime = '';
            return Action.CreateCDO_DO_Template(record).Record.ID";
            ExprResult exprResult = ExprService.GetInstance.JSExecute(expr, dic);
            Assert.IsTrue(exprResult.Result.ToString() == ID);

            expr = $"Action.GetCDO_DO_Template('{ID}').Record.ID";
            exprResult = ExprService.GetInstance.JSExecute(expr, dic);
            Assert.IsTrue(exprResult.Result.ToString() == ID);

            expr = $@"var record = Action.GetCDO_DO_Template('{ID}').Record;
            record.Code='33'
            return Action.UpdateCDO_DO_Template(record).Record.Code";
            exprResult = ExprService.GetInstance.JSExecute(expr, dic);
            Assert.IsTrue(exprResult.Result.ToString() == "33");

            expr = $"Action.DeleteCDO_DO_Template('{ID}')";
            exprResult = ExprService.GetInstance.JSExecute(expr, dic);
            Assert.IsTrue(exprResult.State == ResultState.Success);

            expr = $"Action.GetCDO_DO_Template('{ID}').Record.ID";
            exprResult = ExprService.GetInstance.JSExecute(expr, dic);
            Assert.IsTrue(exprResult.Result == null);
        }
        /// <summary>
        /// DQ
        /// </summary>
        [TestMethod]
        public void ExecuteDQ()
        {
            Dictionary<string, object> dic = new Dictionary<string, object>();
            var expr = @"var advFilter = {'ElementType':'Group','Filters':[]}
                return DataQuery.DQ_DO_Template('',1,20,JSON.stringify(advFilter),'')";
            ExprResult exprResult = ExprService.GetInstance.JSExecute(expr, dic);
            Assert.IsTrue(exprResult.State == ResultState.Success);
            var s = exprResult.Result as TCommonResult<TRecord>;
            Assert.IsTrue(s.Count > 0);
        }
        #region Create
        /// <summary>
        /// CDOAction Create
        /// </summary> 
        private TResult ExecuteByAction(int index)
        {
            string ID = "test" + index;
            Dictionary<string, object> dic = new Dictionary<string, object>();
            dic.Add("ActionID", null);
            dic.Add("ActionCode", null);
            dic.Add("ActionName", null);
            dic.Add("ID", ID);
            dic.Add("Code", "1");
            dic.Add("Name", "2");
            dic.Add("Creator", "");
            dic.Add("CreateTime", "");
            dic.Add("LastModifier", "");
            dic.Add("LastModifierName", "");
            dic.Add("LastModifyTime", "");
            TRecord record = new TRecord(dic);
            List<ActionParameter> parameters = new List<ActionParameter>();
            parameters.Add(new ActionParameter { Order = 0, ParameterName = "TRecord", ParameterValue = record });
            TResult result = ActionExecuteService.GetInstance.Execute("CreateCDO_DO_Template", ActionType.Action, parameters, true);
            return result;
        }
        private ExprResult ExecuteByExpression(int index)
        {
            string ID = "test" + index;
            Dictionary<string, object> dic = new Dictionary<string, object>();
            var expr = "var record = {};";
            expr += $@"
                record.ActionID = null;
                record.ActionCode = null;
                record.ActionName = null;
                record.ID = '{ID}';
                record.Code = '1';
                record.Name = '2';
                record.Creator = '';
                record.CreateTime = '';
                record.LastModifier = '';
                record.LastModifierName = '';
                record.LastModifyTime = '';
                return Action.CreateCDO_DO_Template(record).Record.ID";
            ExprResult exprResult = ExprService.GetInstance.JSExecute(expr, dic);
            return exprResult;
        }

        /// <summary>
        /// 表达式执行
        /// </summary>
        [TestMethod]
        public void ExecuteCSharpBeginTransaction()
        {
            var db = DatabaseHelper.GetDatabaseByConnectionKey("DB_Template.Config.All");
            List<ActionParameter> parameters = new List<ActionParameter>();
            Dictionary<string, object> dic = new Dictionary<string, object>();
            dic.Add("ID", "1234");
            dic.Add("Code", "1");
            dic.Add("Name", "2");
            TRecord record = new TRecord(dic);
            var trans = db.BeginTransaction();
            try
            {
                parameters.Add(new ActionParameter { Order = 0, ParameterName = "TRecord", ParameterValue = record });
                TResult result = ActionExecuteService.GetInstance.Execute("CreateCDO_DO_TemplateV2", FAS.Runtime.Action.SPI.ActionType.Action, parameters, true);

                //parameters = new List<ActionParameter>();
                //dic["ID"] = Guid.NewGuid() + "123";
                //record = new TRecord(dic);
                //parameters.Add(new ActionParameter { Order = 0, ParameterName = "TRecord", ParameterValue = record });
                //ActionExecuteService.GetInstance.Execute("CreateCDO_DO_TemplateV2", FAS.Runtime.Action.SPI.ActionType.Action, parameters, true);
                trans.Commit();
                Assert.IsNotNull(result);
            }
            catch
            {
                trans.Rollback();
            }
            finally
            {
                trans.Dispose();
            }
        }
        /// <summary>
        /// 表达式执行
        /// </summary>
        [TestMethod]
        public void ExecuteActionExprTransactionScope()
        {
            Dictionary<string, object> dic = new Dictionary<string, object>();
            var expr = "var record = {};";
            expr += @"
            record.ID = '1234';
            record.Code = '1';
            record.Name = '2';
            var scope = new System.Transactions.TransactionScope();
            try{
                Action.CreateCDO_DO_TemplateV2(record);
                scope.Complete();
                scope.Dispose();
            } catch(e){
                Log.Log(JSON.stringify(e))
            } finally {
                scope.Dispose();
            }";
            ExprResult exprResult = ExprService.GetInstance.JSExecute(expr, dic);
            Assert.IsTrue(exprResult.State == ResultState.Fail);
        }
        [TestMethod]
        public void CDOAction()
        {
            Func<object, object> ExecuteAction = (object obj) =>
            {
                int index = (int)obj;
                return ExecuteByAction(index);
            };
            var actionTasks = new List<Task<object>>();
            Stopwatch watchAction = new Stopwatch();
            watchAction.Start();
            for (int i = 0; i < 100; i++)
            {
                actionTasks.Add(Task.Factory.StartNew(ExecuteAction, i));
            }
            Task.WaitAll(actionTasks.ToArray());
            watchAction.Stop();
            Console.WriteLine($"Action执行耗时：{watchAction.ElapsedMilliseconds}");

            var exprTasks = new List<Task<object>>();
            Func<object, object> ExecuteExpression = (object obj) =>
            {
                int index = (int)obj;
                return ExecuteByExpression(index);
            };
            Stopwatch watchExpr = Stopwatch.StartNew();//创建一个监听器
            for (int i = 100; i < 200; i++)
            {
                exprTasks.Add(Task.Factory.StartNew(ExecuteExpression, i));
            }
            Task.WaitAll(exprTasks.ToArray());
            watchExpr.Stop();
            Assert.IsNotNull(watchExpr);
        }
        [TestMethod]
        public void CDOActionCreate()
        {
            Stopwatch watchExpr = new Stopwatch();
            List<Task> actionTasks = new List<Task>();
            watchExpr.Start();
            for (int i = 0; i < 100; i++)
            {
                actionTasks.Add(Task.Factory.StartNew((object obj) =>
                {
                    int index = (int)obj;
                    ExecuteByAction(index);
                }, i));
            }
            Task.WaitAll(actionTasks.ToArray());
            watchExpr.Stop();
            Assert.IsNotNull(watchExpr);
        }
        [TestMethod]
        public void CDOExpressionCreate()
        {
            Stopwatch watchExpr = new Stopwatch();
            List<Task> exprTasks = new List<Task>();
            watchExpr.Start();
            for (int i = 100; i < 200; i++)
            {
                exprTasks.Add(Task.Factory.StartNew((object obj) =>
                {
                    int index = (int)obj;
                    ExecuteByExpression(index);
                }, i));
            }
            Task.WaitAll(exprTasks.ToArray());
            watchExpr.Stop();
            Assert.IsNotNull(watchExpr);
        }
        /// <summary>
        /// CDOAction Create
        /// </summary> 
        [TestMethod]
        public void ExecuteCDOActionThread()
        {
            Stopwatch watchAction = new Stopwatch();
            watchAction.Start();
            Parallel.For(0, 50, (i, LoopState) =>
            {
                ExecuteByAction(i);
            });
            watchAction.Stop();
            Console.WriteLine($"Action执行耗时：{watchAction.ElapsedMilliseconds}");

            Stopwatch watchExpr = new Stopwatch();
            watchExpr.Start();
            Parallel.For(100, 150, (i, LoopState) =>
            {
                ExecuteByExpression(i);
            });
            watchExpr.Stop();
            Assert.IsNotNull(watchExpr);
        }
        /// <summary>
        /// CDOAction Create
        /// </summary> 
        [TestMethod]
        public void ExecuteCDOActionPerformanceCreate()
        {
            Stopwatch watchAction = new Stopwatch();
            watchAction.Start();
            for (int i = 0; i < 100; i++)
            {
                ExecuteByAction(i);
            }
            watchAction.Stop();
            Console.WriteLine($"Action执行耗时：{watchAction.ElapsedMilliseconds}");

            Stopwatch watchExpr = new Stopwatch();
            watchExpr.Start();
            for (int i = 100; i < 200; i++)
            {
                ExecuteByExpression(i);
            }
            watchExpr.Stop();
            Assert.IsNotNull(watchExpr);
        }
        #endregion
        #region Delete
        private TResult DeleteByAction(int index)
        {
            string ID = "test" + index;
            List<ActionParameter> parameters = new List<ActionParameter>();
            parameters.Add(new ActionParameter { Order = 0, ParameterName = "ID", ParameterValue = ID });
            TResult result = ActionExecuteService.GetInstance.Execute("DeleteCDO_DO_Template", ActionType.Action, parameters, true);
            return result;
        }
        private ExprResult DeleteByExpression(int index)
        {
            string ID = "test" + index;
            Dictionary<string, object> dic = new Dictionary<string, object>();
            var expr = $"Action.DeleteCDO_DO_Template('{ID}')";
            ExprResult exprResult = ExprService.GetInstance.JSExecute(expr, dic);
            return exprResult;
        }
        /// <summary>
        /// CDOAction Delete
        /// </summary>
        [TestMethod]
        public void ExecuteCDOActionPerformanceDelete()
        {
            Stopwatch watchAction = new Stopwatch();
            watchAction.Start();
            for (int i = 0; i < 100; i++)
            {
                DeleteByAction(i);
            }
            watchAction.Stop();
            Console.WriteLine($"Action执行耗时：{watchAction.ElapsedMilliseconds}");

            Stopwatch watchExpr = new Stopwatch();
            watchExpr.Start();
            for (int i = 100; i < 200; i++)
            {
                DeleteByExpression(i);
            }
            watchExpr.Stop();
            Assert.IsNotNull(watchExpr);
        }
        #endregion
        #region Get
        private TResult GetByAction(int index)
        {
            string ID = "test" + index;
            List<ActionParameter> parameters = new List<ActionParameter>();
            parameters.Add(new ActionParameter { Order = 0, ParameterName = "ID", ParameterValue = ID });
            TResult result = ActionExecuteService.GetInstance.Execute("GetCDO_DO_Template", ActionType.Action, parameters, true);
            return result;
        }
        private ExprResult GetByExpression(int index)
        {
            string ID = "test" + index;
            Dictionary<string, object> dic = new Dictionary<string, object>();
            var expr = $"Action.GetCDO_DO_Template('{ID}')";
            ExprResult exprResult = ExprService.GetInstance.JSExecute(expr, dic);
            return exprResult;
        }
        /// <summary>
        /// CDOAction Get
        /// </summary>
        [TestMethod]
        public void ExecuteCDOActionPerformanceGet()
        {
            Stopwatch watchAction = new Stopwatch();
            watchAction.Start();
            for (int i = 0; i < 100; i++)
            {
                GetByAction(i);
            }
            watchAction.Stop();
            Console.WriteLine($"Action执行耗时：{watchAction.ElapsedMilliseconds}");

            Stopwatch watchExpr = new Stopwatch();
            watchExpr.Start();
            for (int i = 100; i < 200; i++)
            {
                GetByExpression(i);
            }
            watchExpr.Stop();
            Assert.IsNotNull(watchExpr);
        }
        #endregion
        /// <summary>
        /// 表达式执行
        /// </summary>
        [TestMethod]
        public void ExecuteActionCSharpTransactionScope()
        {
            using (TransactionScope scope = new TransactionScope())
            {
                List<ActionParameter> parameters = new List<ActionParameter>();
                Dictionary<string, object> dic = new Dictionary<string, object>();
                dic.Add("ID", "1234");
                dic.Add("Code", "1");
                dic.Add("Name", "2");
                TRecord record = new TRecord(dic);
                parameters.Add(new ActionParameter { Order = 0, ParameterName = "TRecord", ParameterValue = record });
                TResult result = ActionExecuteService.GetInstance.Execute("CreateCDO_DO_T2022012401", FAS.Runtime.Action.SPI.ActionType.Action, parameters, true);
                ActionExecuteService.GetInstance.Execute("CreateCDO_DO_T2022012401", FAS.Runtime.Action.SPI.ActionType.Action, parameters, true);
                ActionExecuteService.GetInstance.Execute("CreateCDO_DO_T2022012401", FAS.Runtime.Action.SPI.ActionType.Action, parameters, true);
                Assert.IsNotNull(result);
            }
        }
        /// <summary>
        /// 表达式执行
        /// </summary>
        [TestMethod]
        public void ExecuteExprBeginTransaction2()
        {
            Dictionary<string, object> dic = new Dictionary<string, object>();
            var expr = "var record = {};";
            expr += @"
            record.ID = '1234';
            record.Code = '1';
            record.Name = '2';
            var db = DatabaseHelper.GetDatabaseByConnectionKey('DB_Template.Config.All');
            var trans = db.BeginTransaction();
            try
            {
                Action.CreateCDO_DO_TemplateV2(record);
                record.ID = '12345';
                Action.CreateCDO_DO_TemplateV2(record);
                Action.CreateCDO_DO_TemplateV2(record);
                trans.Commit();
            }
            catch(e)
            {
                trans.Rollback();
            }
            finally
            {
                trans.Dispose();
            }";
            ExprResult exprResult = ExprService.GetInstance.JSExecute(expr, dic);
            Assert.IsTrue(exprResult.State == ResultState.Success);
        }
        [TestMethod]
        public void Watch()
        {
            Stopwatch watch = new Stopwatch();
            watch.Start();
            Thread.Sleep(1000);
            Console.WriteLine($"Express执行耗时：{watch.ElapsedMilliseconds}");
            Thread.Sleep(1000);
            Console.WriteLine($"Express执行耗时：{watch.ElapsedMilliseconds}");
            Thread.Sleep(1000);
            Console.WriteLine($"Express执行耗时：{watch.ElapsedMilliseconds}");
            Thread.Sleep(1000);
            Console.WriteLine($"Express执行耗时：{watch.ElapsedMilliseconds}");
            watch.Stop();
            Console.WriteLine($"Express执行耗时：{watch.ElapsedMilliseconds}");
        }
    }
}
